package com.example.demo.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.XmlUtil;
import com.example.demo.config.ErpConfig;
import com.example.demo.vo.GenIqcDataVo;
import com.example.demo.vo.XmlResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import javax.swing.text.Document;
import javax.xml.soap.*;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
@Slf4j
public class SoapXmlUtil {
    public static final String end = "&lt;/Master&gt;\n" +
            "               &lt;/RecordSet&gt;\n" +
            "             &lt;/Document&gt;\n" +
            "           &lt;/RequestContent&gt;\n" +
            "          &lt;/Request&gt;\n" +
            "         ]]&gt;\n" +
            "        &lt;/param&gt;\n" +
            "    &lt;/payload&gt;\n" +
            "&lt;/request&gt;\n" +
            "</request>\n" +
            "      </tip:invokeSrv>\n" +
            "   </soapenv:Body>\n" +
            "</soapenv:Envelope>";

    public static final String LIST_END = "               &lt;/RecordSet&gt;\n" +
            "             &lt;/Document&gt;\n" +
            "           &lt;/RequestContent&gt;\n" +
            "          &lt;/Request&gt;\n" +
            "         ]]&gt;\n" +
            "        &lt;/param&gt;\n" +
            "    &lt;/payload&gt;\n" +
            "&lt;/request&gt;\n" +
            "</request>\n" +
            "      </tip:invokeSrv>\n" +
            "   </soapenv:Body>\n" +
            "</soapenv:Envelope>";

    @Autowired
    private ErpConfig erpConfig;

    public <T, K> String getSoapXml(String serviceName, String masterTableName, String detailTableName, T obj, List<K> objs) {

        String start = getSoapXmlStartJson(serviceName, masterTableName);
        //组装请购需求主表xml
        String mainTableXml = getXmlFromObject(obj);
        mainTableXml = "\n&lt;Record&gt;\n" +
                //"&lt;Field name='ActionType' value='I'/&gt;\n" +
                mainTableXml + "&lt;/Record&gt;";

        //组装请购需求物料附表xml
        String detailTableXml = "";
        //子表有数据时进行拼接
        if (CollUtil.isNotEmpty(objs)){
            for (K objDetail : objs) {
                String temp = getXmlFromObject(objDetail);
                detailTableXml = detailTableXml + "&lt;Record&gt;\n" + temp + "&lt;/Record&gt;\n";
            }
            detailTableXml = "&lt;Detail name='" + detailTableName + "' node_id='1_1'&gt;\n" + detailTableXml + "&lt;/Detail&gt;\n";
        }
        return start + mainTableXml + detailTableXml + end;
    }

    public <T> String getSoapXml(String serviceName, String masterTableName, T obj) {
        //正理生能项目回填ERP协议框架
        String start = getSoapXmlStartJson(serviceName, masterTableName);

        //组装请购需求主表xml
        String mainTableXml = getXmlFromObject(obj);
        mainTableXml = "\n&lt;Record&gt;\n" +
                //"&lt;Field name='ActionType' value='I'/&gt;\n" +
                mainTableXml + "&lt;/Record&gt;";

        return start + mainTableXml  + end;
    }

    private String getXmlFromObject(Object obj) {
        String result = "";

        Field[] fields = obj.getClass().getDeclaredFields();

        for (Field item : fields) {
            try {
                item.setAccessible(true);
                result = result + "&lt;Field name=" + "'" + item.getName() + "'" + " value=" + "'" + item.get(obj) + "'" + "/&gt;\n";
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return result;
    }

    public String sendSoapMessage(SOAPMessage message,String erpUrl) {
        String xmlData = "";
        try {
            // 创建连接
            SOAPConnectionFactory soapConnFactory = SOAPConnectionFactory.newInstance();
            SOAPConnection soapConn = soapConnFactory.createConnection();
            URL url = new URL(erpUrl);
            // 响应消息
            SOAPMessage reply = soapConn.call(message, url);
            // 创建soap消息转换对象
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            // 提取消息内容
            Source sourceContent = reply.getSOAPPart().getContent();
            //输出流
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            StreamResult result = new StreamResult(out);
            //sourceContent实现此接口的对象包含充当源输入（XML 源或转换指令）所需的信息
            //result充当转换结果的持有者，可以为 XML、纯文本、HTML 或某些其他格式的标记
            transformer.transform(sourceContent, result);
            //返回结果
            xmlData = new String(out.toByteArray());
            //关闭连接
            soapConn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return xmlData;
    }

    public String sendSoapMessageNew(String resMessage,String erpUrl) {
        if (ObjectUtil.isEmpty(resMessage)){
            log.info("发送消息为空，请确认！");
            return null;
        }

        String xmlData = "";
        try {
            MessageFactory msgFactory = MessageFactory.newInstance();
            SOAPMessage message = msgFactory.createMessage();
            SOAPPart soapPart = message.getSOAPPart();
            byte[] buffer = resMessage.getBytes();
            ByteArrayInputStream stream = new ByteArrayInputStream(buffer);
            StreamSource source = new StreamSource(stream);
            soapPart.setContent(source);
            message.writeTo(System.out);

            // 创建连接
            SOAPConnectionFactory soapConnFactory = SOAPConnectionFactory.newInstance();
            SOAPConnection soapConn = soapConnFactory.createConnection();
            URL url = new URL(erpUrl);
            // 响应消息
            SOAPMessage reply = soapConn.call(message, url);
            // 创建soap消息转换对象
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            // 提取消息内容
            Source sourceContent = reply.getSOAPPart().getContent();
            //输出流
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            StreamResult result = new StreamResult(out);
            //sourceContent实现此接口的对象包含充当源输入（XML 源或转换指令）所需的信息
            //result充当转换结果的持有者，可以为 XML、纯文本、HTML 或某些其他格式的标记
            transformer.transform(sourceContent, result);
            //返回结果
            xmlData = new String(out.toByteArray());
            //关闭连接
            soapConn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return xmlData;
    }

    public  XmlResp analysisXml(String result) {
        String status ="";
        String[] split = result.split("&lt;");
        for (String s : split) {
            if(s.contains("Status")){
                status = s;
                break;
            }
        }
        String substring = status.substring(7, status.length() - 8);
        String[] split1 = substring.split("\"");
        XmlResp xmlResp = new XmlResp();
        xmlResp.setCode(split1[1]);
        xmlResp.setMessage(split1[5]);
        if(xmlResp.getCode().equals("0")){
            Map<String, String> data = new HashMap<String,String>();
            for (String s : split) {
                if(s.contains("Field")){
                    String[] fields = s.split("\"");
                    data.put(fields[1], fields[3]);
                }
            }
            xmlResp.setData(data);
        }

        //System.out.println(xmlResp);
        log.info("xmlResp: {}", xmlResp);
        return xmlResp;
    }

    public <K> String getSoapXmlList(String serviceName, String masterTableName, List<K> objs) {
        String start = getSoapXmlStartJson(serviceName);
        //组装请购需求物料附表xml
        String detailTableXml = "";
        //子表有数据时进行拼接
        if (CollUtil.isNotEmpty(objs)){
            int k = 0;
            for (int i = 0; i < objs.size(); i++) {
                k = i+1;
                K objDetail = objs.get(i);
                String temp = getXmlFromObject(objDetail);
                detailTableXml = detailTableXml + "&lt;Master name='" + masterTableName + "' node_id='"+k+"'&gt;"
                        +"&lt;Record&gt;\n" + temp + "&lt;/Record&gt;\n" + "&lt;/Master&gt;\n";
            }
//            for (K objDetail : objs) {
//                String temp = getXmlFromObject(objDetail);
//                detailTableXml = detailTableXml + "&lt;Record&gt;\n" + temp + "&lt;/Record&gt;\n";
//            }
        }
        return start + detailTableXml  + LIST_END;
    }




    public String getSoapXmlStartJson(String serviceName, String masterTableName) {
        //正理生能项目回填ERP协议框架
        String start = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tip=\"http://www.digiwin.com.cn/tiptop/TIPTOPServiceGateWay\">\n" +
                "   <soapenv:Header/>\n" +
                "   <soapenv:Body>\n" +
                "      <tip:invokeSrv>\n" +
                "         <request>&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\n" +
                "&lt;request type=\"sync\" key=\"d41d8cd98f00b204e9800998ecf8427e\"&gt;\n" +
                "    &lt;host prod=\"AMA\" ver=\"1.0\" ip=\"10.0.0.1\" id=\"\" lang=\"zh_CN\" timezone=\"+8\" timestamp=\"" + System.currentTimeMillis() + "\" acct=\"tiptop\"/&gt;\n" +
                "    &lt;service prod=\"T100\" name=\"" + serviceName + "\" srvver=\"1.0\" ip=\"" + erpConfig.getIp() + "\" id=\"" + erpConfig.getId() + "\"/&gt;\n" +
                "    &lt;datakey type=\"FOM\"&gt;\n" +
                "        &lt;key name=\"EntId\"&gt;5&lt;/key&gt;\n" +
                "        &lt;key name=\"CompanyId\"&gt;AMA&lt;/key&gt;\n" +
                "    &lt;/datakey&gt;\n" +
                "    &lt;payload&gt;\n" +
                "        &lt;param key=\"data\" type=\"XML\"&gt;\n" +
                "            &lt;![CDATA[\n" +
                "            &lt;Request&gt;\n" +
                "             &lt;RequestContent&gt;\n" +
                "              &lt;Document&gt;\n" +
                "               &lt;RecordSet id='1'&gt;\n" +
                "                &lt;Master name='" + masterTableName + "' node_id='1'&gt;";
        return start;
    }


    public String getSoapXmlStartJson(String serviceName) {
        //正理生能项目回填ERP协议框架
        String start = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tip=\"http://www.digiwin.com.cn/tiptop/TIPTOPServiceGateWay\">\n" +
                "   <soapenv:Header/>\n" +
                "   <soapenv:Body>\n" +
                "      <tip:invokeSrv>\n" +
                "         <request>&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\n" +
                "&lt;request type=\"sync\" key=\"d41d8cd98f00b204e9800998ecf8427e\"&gt;\n" +
                "    &lt;host prod=\"AMA\" ver=\"1.0\" ip=\"10.0.0.1\" id=\"\" lang=\"zh_CN\" timezone=\"+8\" timestamp=\"" + System.currentTimeMillis() + "\" acct=\"tiptop\"/&gt;\n" +
                "    &lt;service prod=\"T100\" name=\"" + serviceName + "\" srvver=\"1.0\" ip=\"" + erpConfig.getIp() + "\" id=\"" + erpConfig.getId() + "\"/&gt;\n" +
                "    &lt;datakey type=\"FOM\"&gt;\n" +
                "        &lt;key name=\"EntId\"&gt;5&lt;/key&gt;\n" +
                "        &lt;key name=\"CompanyId\"&gt;AMA&lt;/key&gt;\n" +
                "    &lt;/datakey&gt;\n" +
                "    &lt;payload&gt;\n" +
                "        &lt;param key=\"data\" type=\"XML\"&gt;\n" +
                "            &lt;![CDATA[\n" +
                "            &lt;Request&gt;\n" +
                "             &lt;RequestContent&gt;\n" +
                "              &lt;Document&gt;\n" +
                "               &lt;RecordSet id='1'&gt;\n";
        return start;
    }
}
